<script setup lang="ts">
import { ref, onMounted, reactive, computed, watch, toRaw } from "vue";
import { getDeviceConfigApi, setDeviceConfigApi } from '@/api/configs/deviceConfig';
import { useI18n } from "vue-i18n";
import { IsBelongAe, IsBelongM1, IsBelongM2, IsLora } from "@/utils/appCommon/appCommonOptions/products";
import { DeviceModel } from "@/api/products/device";
import { formatTimestampToDatetime, getDateTimePickShortCut } from "@/utils/appCommon/timeUtil";
import { ElMessageBox, ElMessage } from "element-plus";
import { QuestionFilled,Tools } from '@element-plus/icons-vue';
import Vue3CronCore from "@/components/vue3-cron-core/Index.vue";
import { cron2human, nextCronScheduleList } from "@/utils/appCommon/cronUtil";
import { round } from "lodash";
import { useAppStore, useAppStoreHook } from "@/store/modules/app";
import en from "element-plus/es/locale/lang/en";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import CopyDevices from './CopyDevices.vue';

const emit = defineEmits(['onsubmit']);

const pureApp = useAppStoreHook();

const props = defineProps({
  params: {
    type: Object,
    required: true
  },
  deviceNo: {
    type: String,
    required: true
  },
  deviceOptions: {
    type: Array,
    required: false,
    default: [],
  },
  forceRefresh: {
    type: Number,
    required: false,
    default: 0
  }
});

// TypeScript接口定义，对应后端结构体
interface AeCronItem {
  start?: number | undefined;
  end?: number | undefined;
  cron: string;
}

interface AeFixedTimingListItem {
  range: number[];
}

interface AeTimingConfig {
  aeTimingType: number;
  aeTimingSleep: number;
  aeTimingEnable: boolean;
  aeTimingLength: number;
  aeFixedTimingList: AeFixedTimingListItem[];
  crons: AeCronItem[];
  updatetime?: number;
}

const i18n = useI18n();

const current = ref({
  configKey: "timing", // 固定configKey为timing
  deviceNo: "",
  productId: 0,
  productKey: "",
  updatedAt: 0,
});

const currentDeviceInfo = ref<DeviceModel>();
// 复制设备配置
const copyDevices = ref<string[]>([]);

// 表单数据初始化
const form = ref<AeTimingConfig>({
  aeTimingType: 0,
  aeTimingSleep: 0,
  aeTimingEnable: false,
  aeTimingLength: 0,
  aeFixedTimingList: [],
  crons: [],
});

// 定时类型选项
const timingTypeOptions = [
  { label: i18n.t('device.aetiming.CONTINUOUS'), value: 0 },
  { label: i18n.t('device.aetiming.FIXED_INTERVAL'), value: 1 },
  { label: i18n.t('device.aetiming.COMPLICATED_SCHEDULE'), value: 2 },
];

// Cron相关状态
const cronState = reactive({
  cronData: {
    cron: '* * * * * ?',
    index: undefined,
  },
  dialogVisible: false,
  dialogVisible2: false,
  informationData: {
    cron: "",
    cronHuman: "",
    gridData: [],
    start: null,
    end: null,
  }
});

// 日期选择器快捷选项
const shortcuts1 = getDateTimePickShortCut();

// 监听属性变化，加载配置
watch(
  () => props,
  (newVal) => {
    current.value.updatedAt=0
    current.value.deviceNo = newVal.deviceNo;
    current.value.productId = newVal.params.productId;
    current.value.productKey = newVal.params.productKey;
    setTimeout(async () => {
      await loadConfig();
    });
  },
  {
    deep: true, immediate: true
  }
);

// 格式化系统时间
const systemTime = computed(() => {
  if (!current.value.updatedAt || current.value.updatedAt == 0) {
    return "-";
  }
  return formatTimestampToDatetime(current.value.updatedAt);
});

const loading = ref(false);

// 时间戳转换工具函数
const getTimeObjTimestamp = (time: Date | number) => {
  // 解决用户手动更改时间组件time.getTime()报错问题
  const parsedDate = new Date(time);
  return round(parsedDate.getTime() / 1000);
};

const getTimestampObj = (time: number) => {
  return new Date(time * 1000);
};

// 加载配置
const loadConfig = async () => {
  try {
    loading.value = true;
    const res = await getDeviceConfigApi({
      deviceNo: current.value.deviceNo,
      configKey: current.value.configKey,
    });
    if (res.data?.configValue) {
      form.value = JSON.parse(res.data?.configValue);
      form.value.updatetime =  res.data?.updatedAt
      // 确保数组不为空
      if (!form.value.aeFixedTimingList || form.value.aeFixedTimingList.length === 0) {
        form.value.aeFixedTimingList = [];
      } else {
        // 处理aeFixedTimingList数组，转换秒级时间戳为毫秒级
        form.value.aeFixedTimingList = form.value.aeFixedTimingList.map((item: any) => {
          const newItem = { ...item };
          // 确保range数组存在且长度为2
          if (!newItem.range || !Array.isArray(newItem.range)) {
            newItem.range = [0, 0];
          } else if (newItem.range.length !== 2) {
            // 调整数组长度为2，不足则补0，多余则截断
            while (newItem.range.length < 2) {
              newItem.range.push(0);
            }
            newItem.range = newItem.range.slice(0, 2);
          }
          // 秒级时间戳转为毫秒级时间戳
          newItem.range = newItem.range.map((timestamp: number) => {
            return timestamp > 0 ? timestamp * 1000 : 0;
          });
          return newItem;
        });
      }

      // 处理crons数组，转换时间戳格式
      if (!form.value.crons || !Array.isArray(form.value.crons)) {
        form.value.crons = []; // 确保是数组而非null
      }
      // 转换秒级时间戳为毫秒级时间戳
      if (form.value.crons.length > 0) {
        // 秒级时间戳转为毫秒级时间戳
        form.value.crons = form.value.crons.map((item: any) => {
          const newItem = { ...item };
          if (newItem.start && newItem.start > 0) {
            newItem.start = newItem.start * 1000;
          } else {
            newItem.start = undefined;
          }
          if (newItem.end && newItem.end > 0) {
            newItem.end = newItem.end * 1000;
          } else {
            newItem.end = undefined;
          }
          return newItem;
        });
      }

      // 更新当前时间戳
      if (form.value.updatetime) {
        current.value.updatedAt = form.value.updatetime;
      }
    }
  } finally {
    loading.value = false;
  }
};

// 验证Cron表达式是否有效
const cron2humanOrInvalid = (cron: string): boolean | string => {
  if (!cron) {
    return false;
  }
  const lang = pureApp.globalI18n == "en"  ? 'en' : 'zh_CN';
  try {
    const res = cron2human(cron, lang);
    return res || false;
  } catch (error) {
    return false;
  }
};

// 保存配置
const saveConfig = async () => {
  try {
    loading.value = true;

    // 准备请求数据
    const reqData = { ...toRaw(form.value) };

    // 处理aeFixedTimingList数组，转换毫秒级时间戳为秒级
    if (reqData.aeFixedTimingList && reqData.aeFixedTimingList.length > 0) {
      reqData.aeFixedTimingList = reqData.aeFixedTimingList.map((item: any) => {
        const newItem = { ...item };
        // 确保range数组存在且长度为2
        if (!newItem.range || !Array.isArray(newItem.range)) {
          newItem.range = [0, 0];
        } else if (newItem.range.length !== 2) {
          // 调整数组长度为2，不足则补0，多余则截断
          while (newItem.range.length < 2) {
            newItem.range.push(0);
          }
          newItem.range = newItem.range.slice(0, 2);
        }
        // 毫秒级时间戳转为秒级时间戳
        newItem.range = newItem.range.map((timestamp: number) => {
          return timestamp > 0 ? Math.floor(Number(timestamp) / 1000) : 0;
        });
        return newItem;
      });
    }

    // 处理crons数组，转换时间戳格式
    if (reqData.crons && reqData.crons.length > 0) {
      reqData.crons = reqData.crons.map((item: any) => {
        let start1 = 0;
        let end1 = 0;
        if (item.start) {
          start1 = Math.floor(Number(item.start) / 1000);
        }
        if (item.end) {
          end1 = Math.floor(Number(item.end) / 1000);
        }

        // 验证cron表达式
        const isvalid = cron2humanOrInvalid(item.cron);
        if (!isvalid) {
          ElMessage.error(i18n.t('device.aetiming.INVALID_CRON'));
          throw new Error('Invalid cron expression');
        }

        return {
          start: start1,
          end: end1,
          cron: item.cron
        };
      });
    }

    await setDeviceConfigApi({
      deviceNo: current.value.deviceNo,
      configKey: current.value.configKey,
      configValue: reqData,
      copyDevices: copyDevices.value
    });

    ElMessage.success(i18n.t('buttons.tips.success'));

    // 重新加载配置以更新时间戳
    setTimeout(async ()=>{
      await loadConfig();
    },2000)
  } catch (error) {
    ElMessage.error(i18n.t('buttons.tips.fail'));
    throw error;
  } finally {
    loading.value = false;
  }
};

// 带二次确认的保存方法
const handleSaveConfig = async () => {
  try {
    // 表单验证
    if (!validateForm()) {
      return;
    }

    // 显示确认对话框
    await ElMessageBox.confirm(
      i18n.t('buttons.tips.confirmSaveConfig') + "?",
      "",
      {
        confirmButtonText: i18n.t('buttons.confirm'),
        cancelButtonText: i18n.t('buttons.cancel'),
        type: 'warning'
      }
    );

    // 用户确认后执行保存操作
    await saveConfig();
  } catch (error) {
    // 用户取消或其他错误，不做任何操作
    console.log('保存已取消');
  }
};

// 表单验证
const validateForm = (): boolean => {
  // 1. 验证定时类型为定时间隔时，检查休眠时间
  if (form.value.aeTimingType === 1 && form.value.aeTimingSleep <= 0) {
    ElMessage.error('休眠时间应该>0!');
    return false;
  }

  // 2. 验证固定时间列表（定时类型为2）
  if (form.value.aeTimingType === 2) {
    const timeList = form.value.aeFixedTimingList;
    if (!timeList || timeList.length === 0) {
      ElMessage.error('NO_FIXED_TIMING_LIST');
      return false;
    }

    // 验证每个时间范围的有效性
    for (let i = 0; i < timeList.length; i++) {
      const range = timeList[i].range;
      if (!range || !Array.isArray(range) || range.length < 2) {
        ElMessage.error(`'INVALID_TIME_RANGE' ${i + 1}`);
        return false;
      }

      // 验证单个时间范围的开始时间小于结束时间
      if (range[0] > 0 && range[1] > 0 && range[0] >= range[1]) {
        ElMessage.error(`'TIME_RANGE_INVALID' ${i + 1}`);
        return false;
      }
    }

    // 验证时间范围不重叠且按顺序排列
    for (let i = 0; i < timeList.length - 1; i++) {
      const currentEnd = timeList[i].range[1]; // 当前项的结束时间
      const nextStart = timeList[i + 1].range[0]; // 下一项的开始时间

      // 只有当两个时间都有有效值时才进行比较
      if (currentEnd > 0 && nextStart > 0 && currentEnd >= nextStart) {
        ElMessage.error(`'TIME_RANGE_OVERLAP' ${i + 1} ${i + 2}`);
        return false;
      }
    }
  }

  // 3. 验证复杂定时（Cron模式）
  if (form.value.aeTimingType === 5) {
    for (let i = 0; i < form.value.crons.length; i++) {
      const cron = form.value.crons[i];
      if (!cron.cron) {
        ElMessage.error("cron expression error");
        return false;
      }

      // 验证cron表达式格式
      const isValid = cron2humanOrInvalid(cron.cron);
      if (!isValid) {
        ElMessage.error(`${i18n.t('device.aetiming.INVALID_CRON_ITEM')} ${i + 1}`);
        return false;
      }

      // 验证时间范围（如果有设置）
      if (cron.start>0 && cron.end>0 && cron.start > cron.end) {
        ElMessage.error('start should < end');
        return false;
      }
    }
  }

  return true;
};

// 添加固定时间项
const addFixedTimingItem = () => {
  form.value.aeFixedTimingList.push({ range: [0, 0] });
};

// 删除固定时间项
const removeFixedTimingItem = (index: number) => {
  form.value.aeFixedTimingList.splice(index, 1);
};

// 添加复杂定时项
const addCronItem = () => {
  const end = new Date();
  const start = new Date();
  end.setTime(start.getTime() + 3600 * 1000 * 24);
  form.value.crons.push({
    start: undefined,
    end: undefined,
    cron: ""
  });
};

// 删除复杂定时项
const removeCronItem = (index: number) => {
  form.value.crons.splice(index, 1);
  // 确保crons始终是数组
  if (!form.value.crons || !Array.isArray(form.value.crons)) {
    form.value.crons = [];
  }
};

// 打开Cron工具对话框
const openHelper = (index: number) => {
  cronState.cronData.index = index;
  const obj = form.value.crons[index];
  cronState.cronData.cron = obj.cron || "0 * * * * ?";
  cronState.dialogVisible = true;
};

// Cron值变化处理
const changeCron = (val: any) => {
  if (typeof val !== "string") return false;
  cronState.cronData.cron = val;
};

// 确认Cron表达式
const confirmCron = () => {
  const index: number = cronState.cronData.index!;
  form.value.crons[index].cron = cronState.cronData.cron;
  cronState.dialogVisible = false;
};

// 打开Cron预览对话框
const openInfomation = (index: number) => {
  cronState.informationData.gridData = [];
  const cron = form.value.crons[index].cron;
  const valid = cron2humanOrInvalid(cron);

  if (!cron || !valid) {
    ElMessage.error(i18n.t('device.aetiming.INVALID_CRON'));
    return;
  }

  cronState.informationData.cron = cron;
  cronState.informationData.cronHuman = valid as string;

  const filter = {
    start: form.value.crons[index].start,
    end: form.value.crons[index].end,
  };

  nextScheduleTimes(cron, 10, filter);
  cronState.dialogVisible2 = true;
};

// 获取下一次执行时间列表
const nextScheduleTimes = (cron: string, count: number, filter: any) => {
  try {
    const res = nextCronScheduleList(cron, count, 0, filter);
    const tmp = res.map((o: string) => ({
      date: o
    }));
    cronState.informationData.gridData = tmp;
  } catch (error) {
    console.error('Error getting next schedule times:', error);
    cronState.informationData.gridData = [];
  }
};

// Cron表达式变化处理
const cronChange = (index: number) => {
  // 可以在这里添加额外的cron表达式处理逻辑
};

onMounted(() => {
});
</script>

<template>
  <div class="ae-timing-config">
    <el-form :model="form" class="vertical-form">
      <!-- 设备编号 -->
      <el-form-item :label="i18n.t('device.deviceNo')" prop="deviceNo">
        <el-input v-model="current.deviceNo" disabled style="width: 100%; max-width: 300px;" />
      </el-form-item>

      <!-- 定时启用 -->
      <el-form-item :label="i18n.t('device.aetiming.TIMING_ENABLE')" prop="aeTimingEnable">
        <div style="margin-top: 8px;">
          <el-radio-group v-model="form.aeTimingEnable">
            <el-radio :label="true" style="margin-right: 20px;">{{ i18n.t('buttons.yes') }}</el-radio>
            <el-radio :label="false">{{ i18n.t('buttons.no') }}</el-radio>
          </el-radio-group>
        </div>
      </el-form-item>

      <!-- 定时类型 -->
      <el-form-item :label="i18n.t('device.aetiming.TIMING_TYPE')" prop="aeTimingType">
        <div style="margin-top: 8px;">
          <!-- 1表示为连续采集模式，3表示为间隔采集模式-->
          <el-radio-group v-model="form.aeTimingType">
            <el-radio :label="1" v-if="current.deviceNo && !IsLora(current.deviceNo)">
              {{i18n.t('device.aetiming.TIMING_TYPE_CONTINUOUS')}}
            </el-radio>

            <el-radio :label="2" v-if="current.deviceNo && !IsLora(current.deviceNo) && IsBelongM1(current.productKey)">
              {{i18n.t('device.aetiming.TIMING_TYPE_FIXED')}}
            </el-radio>

            <el-radio :label="3">
              {{i18n.t('device.aetiming.TIMING_TYPE_INTERVAL')}}
            </el-radio>

            <el-radio :label="4" v-if="current.deviceNo  && !IsLora(current.deviceNo) && IsBelongAe(current.productKey)">
              {{i18n.t('device.aetiming.TIMING_TYPE_TRIGGER')}}
            </el-radio>

            <el-radio :label="5" v-if="current.deviceNo && !IsLora(current.deviceNo)">
              {{i18n.t('device.aetiming.TIMING_TYPE_complicate_schedule')}}
            </el-radio>
          </el-radio-group>
        </div>
      </el-form-item>

      <!-- 定时长度 -->
      <div v-if="form.aeTimingType===3">
        <el-form-item :label="i18n.t('device.aetiming.TIMING_LENGTH') + '(sec)'" prop="aeTimingLength"
                      v-if="IsBelongM1(current.productKey)">
          <el-input-number v-model="form.aeTimingLength" :min="1" style="min-width: 200px;" />
        </el-form-item>

        <el-form-item :label="i18n.t('device.aetiming.TIMING_SLEEP') + '(sec)'" prop="aeTimingSleep">
          <el-input-number v-model="form.aeTimingSleep" :min="1" style="min-width: 200px;" />
        </el-form-item>
      </div>

      <div v-if="form.aeTimingType === 2">
        <div style="margin: 3px 20px">
          <el-button type="primary" plain @click="addFixedTimingItem" style="margin-top: 10px;">
            {{ i18n.t('buttons.add') }}
          </el-button>
        </div>
        <el-form-item :label="i18n.t('device.aetiming.TIMING_FIXED_TIME_LIST')">
          <div  v-if="form.aeFixedTimingList" v-for="(o, index) in form.aeFixedTimingList" :key="index" class="timing-item">
            <el-form-item label="" :label-width="0">
              <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
                <el-date-picker
                  v-model="o.range"
                  type="datetimerange"
                  range-separator="To"
                  start-placeholder="Start date"
                  end-placeholder="End date"
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="x"
                />
                <el-button type="danger" size="small" @click="removeFixedTimingItem(index)">
                  {{ i18n.t('buttons.remove') }}
                </el-button>
              </div>
            </el-form-item>
          </div>
        </el-form-item>

      </div>

      <!-- 复杂定时相关配置 -->
      <template v-if="form.aeTimingType === 5">
        <div style="margin-bottom: 15px;">
          <el-button type="primary" plain @click="addCronItem">
            {{ i18n.t('buttons.add') }}
          </el-button>
        </div>

        <el-form-item :label="i18n.t('device.aetiming.COMPLICATED_TIMING_LIST')">
          <div v-for="(cron, index) in form.crons" :key="index" class="cron-item">
            <el-form-item :label="(index + 1).toString()" label-width="30px">
              <div style="display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px;">
                <div style="width: 200px;">
                  <el-date-picker
                    v-model="cron.start"
                    type="datetime"
                    :placeholder="i18n.t('buttons.start')"
                    :shortcuts="shortcuts1"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="x"
                    style="width: 100%;"
                  />
                </div>

                <div style="margin: 0 5px;">To</div>

                <div style="width: 200px;">
                  <el-date-picker
                    v-model="cron.end"
                    type="datetime"
                    :placeholder="i18n.t('buttons.end')"
                    :shortcuts="shortcuts1"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="x"
                    style="width: 100%;"
                  />
                </div>

                <div style="width: 200px;">
                  <el-input
                    :rows="2"
                    type="textarea"
                    v-model="cron.cron"
                    :placeholder="i18n.t('device.aetiming.CRON_EXPRESSION')"
                    @change="cronChange(index)"
                    style="width: 100%;"
                  />
                </div>

                <el-tooltip :content="i18n.t('device.aetiming.CRON_HELPER')" placement="top">
                  <el-button type="text" @click="openHelper(index)">
                    <el-icon :size="20"><Tools /></el-icon>
                  </el-button>
                </el-tooltip>

                <el-tooltip :content="i18n.t('device.aetiming.CRON_INFO')" placement="top">
                  <el-button type="text" @click="openInfomation(index)">
                    <el-icon :size="20"><QuestionFilled /></el-icon>
                  </el-button>
                </el-tooltip>

                <el-button type="danger" size="small" @click="removeCronItem(index)">
                  {{ i18n.t('buttons.delete') }}
                </el-button>
              </div>
            </el-form-item>
          </div>
        </el-form-item>
      </template>

      <!-- 复制设备配置 -->
      <el-form-item :label="i18n.t('device.copyDevices.title')">
        <CopyDevices
          :device-no="current.deviceNo"
          v-model="copyDevices"
        />
      </el-form-item>

      <!-- Cron工具对话框 -->
      <el-dialog :title="i18n.t('device.aetiming.CRON_HELPER')" v-model="cronState.dialogVisible">
        <Vue3CronCore
          i18n="cn"
          maxHeight="350px"
          @change="changeCron"
          v-model:value="cronState.cronData.cron"
          style="flex: 0.4"
        />
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="cronState.dialogVisible = false">{{ i18n.t('buttons.cancel') }}</el-button>
            <el-button type="primary" @click="confirmCron">{{ i18n.t('buttons.confirm') }}</el-button>
          </span>
        </template>
      </el-dialog>

      <!-- Cron预览对话框 -->
      <el-dialog :title="i18n.t('device.aetiming.NEXT_EXECUTION_TIME')" v-model="cronState.dialogVisible2">
        <div style="font-weight: bold; color: #f56c6c; margin-bottom: 15px;">
          {{ cronState.informationData.cron }} : {{ cronState.informationData.cronHuman }}
        </div>
        <el-table :data="cronState.informationData.gridData" style="width: 100%;">
          <el-table-column prop="date" :label="i18n.t('device.aetiming.EXECUTION_TIME')" width="400"></el-table-column>
        </el-table>
      </el-dialog>

      <!-- 系统时间 -->
      <el-form-item :label="i18n.t('device.aeparam.SYSTEM_TIME')">
        <el-input v-model="systemTime" type="text" disabled style="width: 100%; max-width: 300px;" />
      </el-form-item>

      <!-- 提交按钮 -->
      <el-form-item>
        <el-button type="primary" :loading="loading" @click="handleSaveConfig" style="min-width: 150px;">
          {{ i18n.t('buttons.submit') }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped>
.ae-timing-config {
  padding: 20px;
  overflow-x: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .vertical-form .el-form-item {
    max-width: 100%;
  }

  .timing-item .el-form-item__content,
  .cron-item .el-form-item__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }

  .timing-item .el-form-item__content > div,
  .cron-item .el-form-item__content > div {
    flex-wrap: wrap;
  }
}
</style>
